package com.ls.blog.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.ls.blog.entity.*;
import com.ls.blog.mapper.ArticleBodyMapper;
import com.ls.blog.mapper.ArticleMapper;
import com.ls.blog.mapper.ArticleTagMapper;
import com.ls.blog.mapper.CategoryMapper;
import com.ls.blog.api.ArticleService;
import com.ls.blog.api.SysUserService;
import com.ls.blog.api.TagsService;
import com.ls.blog.utils.UserThreadLocal;
import com.ls.blog.vo.*;
import com.ls.blog.vo.params.ArticleParam;
import com.ls.blog.vo.params.PageParams;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @program: myblog
 * @author: lishun
 * @create: 2021-07-05 00:01
 **/
@Service
public class ArticleServiceImpl implements ArticleService {
    @Autowired
    private ArticleMapper articleMapper;
    @Autowired
    private SysUserService sysUserService;
    @Autowired
    private TagsService tagsService;
    @Autowired
    private ArticleBodyMapper articleBodyMapper;
    @Autowired
    private CategoryMapper categoryMapper;
    @Autowired
    private ThreadService threadService;
    @Autowired
    private ArticleTagMapper articleTagMapper;

    @Override
    public List<ArticleVo> listArticlesPage(PageParams pageParams) {



        Page<Article> page = new Page<>(pageParams.getPage(),pageParams.getPageSize());
        /**
         * 根据参数是否为null动态返回分页数据
         */
        List<ArticleVo> articleIPage = articleMapper.
                listArticle(page,null,null);

        //将对象加工成前端需要的对象
//        List<ArticleVo> articleVoList = copyList(articleIPage.getRecords(),true,false,true,true);
//        return articleVoList;
        return articleIPage;
    }

    @Override
    public List<ArticleVo> newArticles(int limit) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Article::getCreateDate);
        queryWrapper.select(Article::getId,Article::getTitle);
        queryWrapper.last("limit "+limit);
        List<Article> articles = articleMapper.selectList(queryWrapper);
        List<ArticleVo> articleVos = copyList(articles, false, false, false,true);
        return articleVos;
    }

    @Override
    public List<ArticleVo> hotArticles(int limit) {
        LambdaQueryWrapper<Article> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.orderByDesc(Article::getViewCounts);
        queryWrapper.select(Article::getId,Article::getTitle);
        queryWrapper.last("limit "+limit);
        List<Article> articles = articleMapper.selectList(queryWrapper);
        List<ArticleVo> articleVos = copyList(articles, true, false, true,true);
        return articleVos;
    }

    @Override
    public ArchiveVo listArchives(Integer current) throws Exception {
        List<ArchiveRecord> archiveRecordList =null;
        Page<ArchiveRecord> page = new Page<>();
        page.setCurrent(current);
        page.setSize(5);
        archiveRecordList =  articleMapper.listArchives(page);

        if (archiveRecordList ==null){
            throw new Exception("请求文章文档失败");
        }
        ArchiveVo archives = new ArchiveVo();
        archives.setRecordList(archiveRecordList);
        archives.setCount(page.getTotal());
        return archives;
    }

    /**
     * 转换 ，由于有些接口不需要其他字段，加个判断
     * @param records
     * @param isAuthor
     * @param isBody
     * @param isTags
     * @return
     */
    private List<ArticleVo> copyList(List<Article> records,boolean isAuthor,boolean isBody,boolean isTags,boolean isCategory) {
        List<ArticleVo> articleVoList = new ArrayList<>();
        for (Article article : records) {
            ArticleVo articleVo = copy(article,isAuthor,isBody,isTags,true);
            articleVoList.add(articleVo);
        }
        return articleVoList;
    }


    /**
     * 根据文章数据从其他表中查询数据
     * @param article
     * @param isAuthor
     * @param isBody
     * @param isTags
     * @return
     */
    public ArticleVo copy(Article article, boolean isAuthor, boolean isBody, boolean isTags,boolean isCategory){
        ArticleVo articleVo = new ArticleVo();
        // 工具复制属性
        BeanUtils.copyProperties(article, articleVo);
        if (isAuthor) {
            //查找作者
            SysUser sysUser = sysUserService.findSysUserById(article.getAuthorId());
            articleVo.setAuthor(sysUser.getNickname());
        }
        //时间格式转化
        articleVo.setCreateDate(new DateTime(article.getCreateDate()).toString("yyyy-MM-dd HH:mm"));
        // 查找标签
        if (isTags){
            List<TagVo> tags = tagsService.findTagsByArticleId(article.getId());
//            articleVo.setTags(tags);
        }
        // 文章主体
        if (isBody){
            ArticleBody articleBody = articleBodyMapper.selectById(article.getBodyId());
            ArticleBodyVo articleBodyVo = new ArticleBodyVo();
            articleBodyVo.setContent(articleBody.getContent());
            articleVo.setArticleBodyVo(articleBodyVo);
        }
        if (isCategory){
            Category category = categoryMapper.selectById(article.getCategoryId());
            articleVo.setCategory(category);
        }
        articleVo.setArticleCover("http://qw2la7oq5.hn-bkt.clouddn.com/02327607-1894-418c-8e89-22036b7f31b9.png");

        return articleVo;
    }

    @Override
    public ArticleVo findArticleById(Long id) {

        Article article = articleMapper.selectById(id);
        ArticleVo articleVo = copy(article, true, true, true, true);
        threadService.updateViewCount(articleMapper,article);
        return articleVo;
    }

    @Override
    public void addCommentCountsByArticleId(Long articleId) {
        articleMapper.addCommentCountsByArticleId(articleId);

    }

    @Override
    public Long publish(ArticleParam articleParam) {
        UserInfo userInfo = UserThreadLocal.get();
        Article article = new Article();
        article.setAuthorId(userInfo.getId());
        ArticleBody articleBody = new ArticleBody();
        BeanUtils.copyProperties(articleParam.getBody(),articleBody);
        // body id要插入之后才会生成id
        articleBodyMapper.insert(articleBody);
        //BodyId自动生成后在赋值给文章
        article.setBodyId(articleBody.getId());
        // 评论数量
        article.setCommentCounts(0);
        // 初始权重0
        article.setWeight(0);
        //初始浏览数量
        article.setViewCounts(0);
        // 分类id
        article.setCategoryId(articleParam.getCategory().getId());

        // 创建时间
        article.setCreateDate(System.currentTimeMillis());
        article.setTitle(articleParam.getTitle());
        article.setSummary(articleParam.getSummary());
        articleMapper.insert(article);
        // 文章id要在生成文章后才会生成
        articleBody.setArticleId(article.getId());
        // 再去修改body里的文章id
        articleBodyMapper.updateById(articleBody);

        List<TagVo> tags = articleParam.getTags();
        ArticleTag articleTag = new ArticleTag();
        for (TagVo tagVo:tags){
            articleTag.setTagId(tagVo.getId());
            articleTag.setArticleId(article.getId());
            articleTagMapper.insert(articleTag);
        }

        return article.getId();
    }

    @Override
    public Map<String,Object> categoryArticles(Long id, Long current) {
        Page page = new Page();
        page.setCurrent(current);
        page.setSize(3);
        List listArticle = articleMapper.listArticle(page, null,id);
//        List list = copyList(listArticle.getRecords(), true,false,true,true);
        Category category = categoryMapper.selectById(id);
        Map<String,Object> map = new HashMap<>();
        map.put("name",category.getCategoryName());
        map.put("articleVoList",listArticle);
        return map;
    }

    @Override
    public Map<String, Object> tagArticles(Long id, Long current) {
        Page page = new Page();
        page.setCurrent(current);
        page.setSize(6);
        List listArticle = articleMapper.listArticle(page,id,null);
        TagVo tagVo = tagsService.findTagsById(id);
        Map<String,Object> map = new HashMap<>();
        map.put("name",tagVo.getTagName());
        map.put("articleVoList",listArticle);
        return map;
    }

}
